<template>
  <div class="container">
    <Breadcrumb :items="['menu.tools', 'menu.tools.test']" />
    <a-spin :loading="spinLoading" :tip="spinTip" dot style="width: 100%;">
      <a-card class="custom-card" title="">
        <a-row>
          <a-col :flex="1">
            <a-form
              :model="query"
              :label-col-props="{ span: 6 }"
              :wrapper-col-props="{ span: 18 }"
              label-align="left"
            >
              <a-row :gutter="16">
                <a-col :span="8">
                  <a-input-group>
                    <a-select v-model="query.keyword_type" placeholder="请选择" :style="{width:'120px'}">
                      <a-option value="name">名称</a-option>
                    </a-select>
                    <a-input v-model="query.name" placeholder="请输入名称" allow-clear />
                  </a-input-group>
                </a-col>
                <a-col :span="8">
                  <a-form-item label="类型" field="">
                    <a-select v-model="query.type" placeholder="" allow-clear>
                      <a-option value="1" label="类型1" />
                      <a-option value="2" label="类型2" />
                      <a-option value="3" label="类型3" />
                    </a-select>
                  </a-form-item>
                </a-col>
                <a-col :span="8">
                  <a-form-item label="状态" field="">
                    <a-select v-model="query.status" :options="statusOptions" placeholder="全部"/>
                  </a-form-item>
                </a-col>
                <a-col :span="12" :style="{'margin-bottom': '20px'}">
                  <a-input-group>
                    <a-select v-model="query.time_type" placeholder="时间类型" :style="{width:'120px'}">
                      <a-option value="created_at" label="添加时间" />
                      <a-option value="updated_at" label="修改时间" />
                    </a-select>
                    <a-range-picker v-model="query.date_value" allow-clear style="width: 100%"/>
                  </a-input-group>
                </a-col>
              </a-row>
            </a-form>
          </a-col>
          <a-divider style="height: 84px" direction="vertical" />
          <a-col :flex="'86px'" style="text-align: right">
            <a-space direction="vertical" :size="18">
              <a-button type="primary" @click="search()">
                <template #icon><icon-search /></template>搜索
              </a-button>
              <a-button status="success" @click="refresh()">
                <template #icon><icon-refresh /></template>重置
              </a-button>
            </a-space>
          </a-col>
        </a-row>
        <a-divider style="margin-top: 0" />
        <a-row style="margin-bottom: 16px">
          <a-col :span="16">
            <a-space>
              <a-checkbox @change="customSelectAll">
                <template #checkbox="{ checked }">
                  <a-space
                    align="start"
                    class="custom-checkbox-card"
                    :class="{ 'custom-checkbox-card-checked': checked }"
                  >
                    <div className="custom-checkbox-card-mask">
                      <div className="custom-checkbox-card-mask-dot" />
                    </div>
                    <div>
                      <div className="custom-checkbox-card-title">全选</div>
                    </div>
                  </a-space>
                </template>
              </a-checkbox>
              <a-button type="primary" status="warning" @click="batchSelect('hide')">批量操作</a-button>
              <a-button type="primary" status="danger" @click="batchDel()">
                <template #icon><icon-delete /></template>批量删除
              </a-button>
              <a-button status="warning" @click="doExport()">
                <template #icon><icon-download /></template>下载
              </a-button>
              <a-upload action="">
                <template #upload-button>
                  <a-button>
                    <template #icon><icon-upload /></template>导入
                  </a-button>
                </template>
              </a-upload>
              <a-button type="primary" @click="add()">
                <template #icon><icon-plus /></template>
                <template #default>添加</template>
              </a-button>
            </a-space>
          </a-col>
          <a-col :span="8" style="text-align: right">
            <a-button-group>
              <a-button @click="refresh()"><template #icon><icon-sync /></template></a-button>
              <a-dropdown position="br" :popup-max-height="false">
                <a-button>
                  列配置 <icon-select-all />
                </a-button>
                <template #content>
                  <a-doption v-for="(fruit, index) in allTableThead" :key="fruit">
                    <a-checkbox-group v-model="defaultTableThead" @change="handleTableThead">
                      <a-checkbox :value="allTableThead[index]">{{ tableTheadOptions[fruit].label }}</a-checkbox>
                    </a-checkbox-group>
                  </a-doption>
                </template>
              </a-dropdown>
            </a-button-group>
          </a-col>
        </a-row>
        <a-table
          ref="tableRef"
          row-key="id"
          :loading="loading"
          :pagination="false"
          :columns="columns"
          :data="renderData"
          :bordered="{ wrapper: true, cell: true }"
          :row-selection="rowSelection"
          column-resizable
          @select="select"
          @selection-change="selectionChange"
          @page-change="onPageChange"
          @page-size-change="onPageSizeChange"
          @sorter-change="sorting"
        >
          <template #status="{ record }">
            <span v-if="record.status === '1'" class="circle"></span>
            <span v-else class="circle pass"></span>
            状态名
          </template>
          <template #operations="{ record }">
            <a-space>
              <a-button v-permission="['admin']" type="text" size="small">查看</a-button>
              <a-button type="primary" size="small" @click="edit(record)"><template #icon><icon-edit /></template>编辑</a-button>
              <a-popconfirm content="确定要删除这条数据吗？" type="warning" position="br" @ok="del([record])">
                <a-button type="primary" status="danger" size="small"><template #icon><icon-delete /></template>删除</a-button>
              </a-popconfirm>
            </a-space>
          </template>
        </a-table>
        <pagination-manage
          v-show="pagination.total > 0"
          :total="pagination.total"
          :current="pagination.current"
          :page-size="pagination.pageSize"
          @pageCBK="onPageChange"
          @pageSizeCBK="onPageSizeChange"
        />
      </a-card>
    </a-spin>

    <a-modal
      v-model:visible="dialogVisible"
      :title="dialogTitle"
      :ok-loading="btnLoading"
      :modal-style="{ width: '60%' }"
      :align-center="false"
      top="15vh"
      :mask-closable="false"
      @cancel="dialogCancel"
      @before-ok="dialogBeforeOk"
    >
      <a-form ref="formRef" :model="formModel">
        <a-form-item
          field="name"
          label="名称"
          required
          :validate-trigger="['change','input']"
          :rules="[
            {
              required: true,
              message: '名称不能为空',
            },
          ]"
          label-col-flex="80px"
        >
          <a-input v-model="formModel.name" placeholder="请输入名称"/>
        </a-form-item>
        <a-form-item field="info" label="详细" label-col-flex="80px">
          <a-textarea v-model="formModel.info" allow-clear :max-length="{ length: 20, errorOnly: true }" show-word-limit/>
        </a-form-item>
        <a-form-item field="status" label="状态" label-col-flex="80px">
          <a-input-number v-model="formModel.status" :step="0.01" :precision="2" :min="1" :max="10" :style="{width:'100px'}"/>
        </a-form-item>
        <a-form-item field="sort" label="排序" label-col-flex="80px">
          <a-input-number v-model="formModel.sorting" mode="button" :style="{width:'160px'}"/>
        </a-form-item>
        <a-form-item field="user_name" label="用户" label-col-flex="80px">
          <a-input-group>
            <a-input v-model="formModel.user_name" placeholder="" :disabled="true" />
            <a-button type="text" @click="addUser">选择用户</a-button>
          </a-input-group>
        </a-form-item>
        <a-form-item field="district" label="地址" label-col-flex="80px">
          <a-cascader
            v-model="formModel.district"
            :options="regionTreeDatas"
            expand-trigger="hover"
            :field-names="{ value: 'id', label: 'name' }"
            placeholder="请选择"
            check-strictly
            allow-search
            allow-clear
            :format-label="regionFormat"
          >
          </a-cascader>
        </a-form-item>
        <a-form-item field="latitude" label="" label-col-flex="80px">
          <a-input v-model="formModel.details" id="mapKeyword" placeholder="请输入请输入详细地址" />
        </a-form-item>
        <a-form-item field="" label="" label-col-flex="80px">
<!--          <AmapMap keyword-id="mapKeyword" :address-detail="{longitude: formModel.longitude, latitude: formModel.latitude}" @mapCallback="mapCallback"/>-->
        </a-form-item>
        <a-form-item field="" label="表单内容" label-col-flex="80px">
          <a-table
            row-key="id"
            :pagination="false"
            :data="formModel.form_content"
            :bordered="{ wrapper: true, cell: true }"
            :scroll="{ x: '100%', y: 'auto' }"
            :draggable="{ type: 'handle', width: 40 }"
            style="width: 100%"
          >
            <template #columns>
              <a-table-column title="字段名" align="center" :width="200">
                <template #cell="{ record, rowIndex }">
                  <a-form-item :field="`form_content.${rowIndex}.name`" label="" hide-label>
                    <a-input v-model="record.name" max-length="40" placeholder="40个字符内"/>
                  </a-form-item>
                </template>
              </a-table-column>
              <a-table-column title="类型" align="center" :width="180">
                <template #cell="{ record, rowIndex }">
                  <a-form-item :field="`form_content.${rowIndex}.type`" label="" hide-label>
                    <a-select v-model="record.type" placeholder="请选择">
                      <a-option v-for="(fieldType, fieldTypeKey) in formContent.fieldTypes" :key="fieldTypeKey" :value="fieldTypeKey" :label="fieldType" />
                    </a-select>
                  </a-form-item>
                </template>
              </a-table-column>
              <a-table-column title="配置" align="center" :width="140">
                <template #cell="{ record, rowIndex }">
                  <a-form-item :field="`form_content.${rowIndex}.input_type`" label="" hide-label>
                    <a-select v-model="record.input_type" placeholder="请选择">
                      <a-option v-for="(inputType, inputTypeKey) in formContent.inputTypes" :key="inputTypeKey" :value="inputTypeKey" :label="inputType" />
                    </a-select>
                  </a-form-item>
                </template>
              </a-table-column>
              <a-table-column title="选项值" align="center" :width="260">
                <template #cell="{ record, rowIndex }">
                  <a-form-item v-if="['2', '3'].includes(record.type)" :field="`form_content.${rowIndex}.option`" label="" hide-label>
                    <a-textarea v-model="record.option" max-length="200" placeholder="多个值以英文逗号分隔" allow-clear/>
                  </a-form-item>
                </template>
              </a-table-column>
              <a-table-column title="操作" align="center" :width="80">
                <template #cell="{ record }">
                  <a-space>
                    <a-button type="primary" status="danger" size="small" @click="delContent(record)"><icon-delete /></a-button>
                  </a-space>
                </template>
              </a-table-column>
            </template>
          </a-table>
        </a-form-item>
        <a-form-item field="" label="" label-col-flex="80px">
          <a-button type="outline" long @click="addContent()">新增内容项</a-button>
        </a-form-item>
      </a-form>
<!--      <template #footer>
        <a-button size="small" @click="cancel">取消</a-button>
        <a-button type="primary" size="small" @click="submit">确定</a-button>
      </template>-->
    </a-modal>

    <SelectUser ref="selectUserRef" :ids="userId" selection-type="radio" @selectCallback="userCallback"/>
  </div>
</template>

<script lang="ts" setup>
  import { computed, ref, reactive, h, compile, getCurrentInstance } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { FormInstance } from '@arco-design/web-vue/es/form';
  import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
  import { Message, Modal } from '@arco-design/web-vue';

  import useLoading from '@/hooks/loading';
  import { apiRegions } from '@/api/common';
  import { DataState, QueryParams, apiList, apiInfo, apiSave, apiDel, apiExport } from '@/api/test';
  import PaginationManage from '@/components/pagination/index.vue';
  import SelectUser from '@/views/components/select-user.vue';
  import AmapMap from '@/components/map/amap.vue';

  const { loading, setLoading } = useLoading(true);
  const { t } = useI18n();
  const { proxy } = getCurrentInstance() as any;
  const baseQuery = () => {
    return {
      page: 1,
      limit: 20,
      keyword_type: 'name',
      name: '',
      type: '1', // 不能用数字
      time_type: 'created_at',
      date_value: [],
      status: '',
    };
  };
  const baseFormModel = {
    id: '',
    created_at: '',
    updated_at: '',
    name: '',
    info: '',
    sorting: 100,
    status: 1,

    user_id: '',
    user_name: '',

    province: '',
    province_id: '',
    city: '',
    city_id: '',
    district: '',
    district_id: '',
    details: '',
    latitude: '',
    longitude: '',

    form_content: [],
  };
  const baseColumns = () => {
    return [
      {
        title: 'ID', dataIndex: 'id',
        align: 'center' as 'left' | 'right' | 'center',
        fixed: 'left' as 'left' | 'right',
        sortable: {sortDirections: ['ascend', 'descend'] as ('ascend' | 'descend')[]},
      },
      {
        title: '名称', dataIndex: 'name',
        align: 'center' as 'left' | 'right' | 'center',
      },
      {
        title: '创建时间', dataIndex: 'created_at',
        align: 'center' as 'left' | 'right' | 'center',
        sortable: {sortDirections: ['ascend', 'descend'] as ('ascend' | 'descend')[]},
      },
      {
        title: '状态', dataIndex: 'status',
        align: 'center' as 'left' | 'right' | 'center',
        slotName: 'status',
      },
      {
        title: '操作', dataIndex: 'operations', width: 160,
        align: 'center' as 'left' | 'right' | 'center',
        fixed: 'right' as 'left' | 'right',
        slotName: 'operations',
      },
    ];
  };

  const columns = ref<any>(baseColumns());
  const formRef = ref<FormInstance>();
  const renderData = ref<DataState[]>([]);
  const query = ref<any>(baseQuery());
  const formModel = ref<any>(baseFormModel);
  const pagination = reactive<any>({});
  const rowSelection = reactive({
    type: 'checkbox' as const,
    showCheckedAll: true,
    // selectedRowKeys: [],
    // defaultSelectedRowKeys: [],
  });
  const statusOptions = computed<SelectOptionData[]>(() => [
    {
      label: '状态一',
      value: 1,
    },
    {
      label: '状态二',
      value: 2,
    },
  ]);

  // const selectionKeys = ref<any>([]);
  let selectionKeys: string[] = []; // 选中项ID
  let selectionDatas: any = []; // 选中项
  const spinLoading = ref(false);
  const spinTip = ref();
  const dialogVisible = ref(false);
  const dialogTitle = ref();
  const btnLoading = ref(false);
  const selectUserRef = ref();
  const userId = ref();
  const regionTreeDatas = ref<any>([]);

  const tableTheadOptions = ref<any>({
    id: {
      label: 'Id',
      field: 'id',
    },
    name: {
      label: '名称',
      field: 'name',
    },
    created_at: {
      label: '创建时间',
      field: 'created_at',
    },
    status: {
      label: '状态',
      field: 'status',
    },
  });
  const allTableThead = ref(['name', 'created_at', 'status']);
  // 默认表头
  const defaultTableThead = ref(['name', 'created_at']);

  const stateObj: any = {
    // dialogVisible: ref(false), // 无效
    // dialogTitle: '',
    // btnLoading: false,

    selectionKeys: [], // 选中项ID
    isSelectAll: false,
  };
  const formContent: any = {
    fieldTypes: {
      1: '单行文本',
      2: '单选',
      3: '多选',
      4: '省市区',
      5: '地图定位',
      6: '时间选择',
      7: '姓名+性别',
      8: '手机号',
    },
    inputTypes: {
      0: '不限',
      1: '数字',
    },
  };

  // 分页
  const onPageChange = (page: number) => {
    fetchData({ ...query.value, page });
  };
  const onPageSizeChange = (limit: number) => {
    query.value.page = 1;
    fetchData({ ...query.value, limit });
  };
  // 列表
  const fetchData = async (
    params: QueryParams = { page: 1, limit: 20 }
  ) => {
    setLoading(true);
    try {
      const { data } = await apiList(params);
      renderData.value = data.data;
      query.value.page = params.page;
      query.value.limit = params.limit;
      pagination.current = params.page;
      pagination.pageSize = params.limit;
      pagination.total = data.total;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  // 添加
  const add = () => {
    dialogVisible.value = true;
    dialogTitle.value = '新增';
    getRegions();
    reset();
  };
  // 编辑
  const edit = async (row: DataState) => {
    dialogVisible.value = true;
    dialogTitle.value = `编辑 ${row.id}`;
    getRegions();
    reset();
    const { data } = await apiInfo({id: row.id});
    formModel.value = data;
  };
  // 删除
  const del = (row: any[]) => {
    if (!row.length) {
      selectMsg();
    } else {
      let title = '删除';
      let message = `确定要删除选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
      let ids = row;
      if (row.length === 1 && row[0].id) {
        title = `${title}ID：${row[0].id}`;
        message = `确定要删除 <span style="color:red">${row[0].name} </span> 这条数据吗？`;
        ids = [row[0].id];
      }
      Modal.warning({
        title,
        content: () => h(compile(message)),
        closable: true,
        hideCancel: false,
        onOk: (async () => {
          setLoading(true);
          try {
            await apiDel({ids});
          } catch (err) {
            setLoading(false);
          } finally {
            fetchData({...query.value});
            setLoading(false);
          }
        }),
      });
    }
  };
  // 提交
  const submit = async (done: any) => {
    btnLoading.value = true;
    try {
      const ruleRes = await formRef.value?.validate();
      // console.log(ruleRes);
      if (!ruleRes) {
        await apiSave(formModel.value);
        done();
      } else {
        done(false);
      }
      fetchData({...query.value});
    } catch (err) {
      done(false);
      btnLoading.value = false;
    } finally {
      done(false);
      btnLoading.value = false;
    }
  };
  // 表单重置
  const reset = async () => {
    formModel.value = baseFormModel;
    await formRef.value?.resetFields();
  };
  // 搜索
  const search = () => {
    query.value.page = 1;
    fetchData({...query.value} as unknown as QueryParams);
  };
  // 刷新
  const refresh = () => {
    query.value = baseQuery();
    fetchData({...query.value});
  };
  // 排序
  const sorting = (dataIndex: string, direction: string) => {
    query.value.sort_field = dataIndex;
    if (direction === 'ascend') {
      query.value.sort_value = 'asc';
      fetchData({...query.value});
    }
    if (direction === 'descend') {
      query.value.sort_value = 'desc';
      fetchData({...query.value});
    }
  };
  // 选择用户
  const addUser = () => {
    userId.value = [formModel.value.user_id];
    selectUserRef.value.initData(userId.value);
  };
  const getRegions = async () => {
    if (regionTreeDatas.value.length <= 0) {
      const { data } = await apiRegions();
      regionTreeDatas.value = data;
    }
  };
  // 地区格式化展示内容
  const regionFormat = (options: any[]) => {
    formModel.value.province = options[0].name;
    if (options[1]) {
      formModel.value.city = options[1].name;
    }
    if (options[2]) {
      formModel.value.district = options[2].name;
    }
    const labels = options.map(option => option.name);
    return labels.join(' / ');
  };

  // 点击行选择器时触发 -- table 表头 【废弃：全选时不触发】
  const select = (rowKeys: any[], rowKey: any, record: any) => {
    selectionKeys = rowKeys;
    if (!rowKeys.includes(rowKey)) {
      selectionDatas.forEach((item: any, index: string) => {
        if (index === rowKey) {
          selectionDatas.splice(index, 1);
        }
      });
    } else {
      selectionDatas[rowKey] = record;
    }
  };
  // 已选择的数据行发生改变时触发 -- table 表头
  const selectionChange = (rowKeys: any[]) => {
    stateObj.selectionKeys = rowKeys;
    selectionDatas = [];
    renderData.value.forEach((record: any, index: number) => {
      const rowKey = record.id;
      if (rowKeys.includes(rowKey) && !selectionDatas[rowKey]) {
        selectionDatas[rowKey] = record;
      }
    });
  };
  // 全选操作 -- 自定义按钮
  const customSelectAll = (value: boolean | any) => {
    proxy.$refs.tableRef.selectAll(value);
  };
  const selectMsg = (message?: string) => {
    Message.info(message || '请选择需要操作的数据');
  };
  // 批量选择
  const batchSelect = (selectType?: string) => {
    console.log(stateObj.selectionKeys);
    if (!stateObj.selectionKeys.length) {
      selectMsg();
    } else {
      console.log(selectType);
    }
  };
  // 批量删除
  const batchDel = () => {
    del(stateObj.selectionKeys);
  };
  // 导出
  const doExport = async () => {
    spinLoading.value = true;
    spinTip.value = '数据下载中，请稍候...';
    await apiExport({...query.value}).then(res => {
      spinLoading.value = false;
      // const blob = new Blob([data], {type: 'application/octet-stream'}); // 转换成二进制对象
      // const url = window.URL.createObjectURL(blob); // 二进制对象转换成url地址
      const { url } = res.data;
      const link = document.createElement('a');
      link.setAttribute('download', '');
      link.style.display = 'none';
      link.href = url;
      // 对下载的文件命名
      // link.download = '';
      document.body.appendChild(link);
      link.click();
      // link.remove();
      document.body.removeChild(link); // 下载完成移除元素
      window.URL.revokeObjectURL(url); // 释放掉blob对象
    }).catch(() => {
      spinLoading.value = false;
    });
  };

  const initColumns = (tableTheads: any) => {
    // columns.value.forEach((item: any, index: number) => {
    //   if (!['id', 'operations'].includes(item.dataIndex) && (!tableTheads || !tableTheads.includes(item.dataIndex))) {
    //     columns.value.splice(index, 1);
    //   }
    // });
    const showColumns: any = [];
    baseColumns().forEach((item: any, index: number) => {
      if (['id', 'operations'].includes(item.dataIndex) || tableTheads.includes(item.dataIndex)) {
        showColumns.push(item);
      }
    });
    columns.value = showColumns;
  };
  // table 列配置
  const handleTableThead = (values: (string | number | boolean)[]) => {
    initColumns(values);
  };

  const dialogCancel = () => {
    dialogVisible.value = false;
  };
  const dialogBeforeOk = (done: any) => {
    submit(done);
    // done();
    // done(false);
  };

  // 选择用户回调
  const userCallback = (selected: any) => {
    console.log(selected);
    if (selected) {
      formModel.value.user_id = selected.id;
      formModel.value.user_name = selected.name;
    }
  };
  // 地图回调
  const mapCallback = (address: any) => {
    console.log(address);
  }

  // 内容项
  const addContent = () => {
    formModel.value.form_content.push({
      id: formModel.value.form_content.length,
      name: '',
      field: '',
      input_type: '',
      option: '',
    });
  };
  const delContent = (row: any) => {
    const index = formModel.value.form_content.indexOf(row);
    if (index !== -1) {
      formModel.value.form_content.splice(index, 1);
    }
  };

  initColumns(defaultTableThead.value);
  fetchData();
</script>

<script lang="ts">
  export default {
    name: 'Test',
  };
</script>

<style scoped lang="less">
  .container {
    padding: 0 20px 20px 20px;
  }
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }

  .arco-table-container .arco-form-item {
    margin-bottom: 0;
  }
</style>
